<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>0.预热篇 | 被删的前端游乐场</title>
    <meta name="generator" content="VuePress 1.8.2">
    
    <meta name="description" content="Just playing around">
    
    <link rel="preload" href="/front-end-playground/assets/css/0.styles.6ad2a9ca.css" as="style"><link rel="preload" href="/front-end-playground/assets/js/app.1e2670bf.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/2.38d016d1.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/3.e3f029cb.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/103.4038836d.js" as="script">
    <link rel="stylesheet" href="/front-end-playground/assets/css/0.styles.6ad2a9ca.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/front-end-playground/" class="home-link router-link-active"><!----> <span class="site-name">被删的前端游乐场</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/front-end-playground/" class="nav-link">概述</a></div><div class="nav-item"><a href="/front-end-playground/front-end-basic/" class="nav-link">前端领域</a></div><div class="nav-item"><a href="/front-end-playground/vue/" class="nav-link">Vue学习</a></div><div class="nav-item"><a href="/front-end-playground/wxapp/" class="nav-link">小程序学习</a></div><div class="nav-item"><a href="/front-end-playground/front-end-others/" class="nav-link router-link-active">百家齐放</a></div><div class="nav-item"><a href="/front-end-playground/front-end-addon/" class="nav-link">前端的进击</a></div><div class="nav-item"><a href="/front-end-playground/front-end-work/" class="nav-link">前端与工作</a></div><div class="nav-item"><a href="/front-end-playground/faq.html" class="nav-link">FAQ</a></div> <a href="https://github.com/godbasin/front-end-playground" target="_blank" rel="noopener noreferrer" class="repo-link">
    Github
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/front-end-playground/" class="nav-link">概述</a></div><div class="nav-item"><a href="/front-end-playground/front-end-basic/" class="nav-link">前端领域</a></div><div class="nav-item"><a href="/front-end-playground/vue/" class="nav-link">Vue学习</a></div><div class="nav-item"><a href="/front-end-playground/wxapp/" class="nav-link">小程序学习</a></div><div class="nav-item"><a href="/front-end-playground/front-end-others/" class="nav-link router-link-active">百家齐放</a></div><div class="nav-item"><a href="/front-end-playground/front-end-addon/" class="nav-link">前端的进击</a></div><div class="nav-item"><a href="/front-end-playground/front-end-work/" class="nav-link">前端与工作</a></div><div class="nav-item"><a href="/front-end-playground/faq.html" class="nav-link">FAQ</a></div> <a href="https://github.com/godbasin/front-end-playground" target="_blank" rel="noopener noreferrer" class="repo-link">
    Github
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0" style="padding-top:10px;"><div class="kitty-main" data-v-2b653b36><span class="stand" data-v-2b653b36></span> <div class="cat" data-v-2b653b36><div class="body" data-v-2b653b36></div> <div class="head" data-v-2b653b36><div class="ear" data-v-2b653b36></div> <div class="ear" data-v-2b653b36></div></div> <div class="face" data-v-2b653b36><div class="nose" data-v-2b653b36></div> <div class="whisker-container" data-v-2b653b36><div class="whisker" data-v-2b653b36></div> <div class="whisker" data-v-2b653b36></div></div> <div class="whisker-container" data-v-2b653b36><div class="whisker" data-v-2b653b36></div> <div class="whisker" data-v-2b653b36></div></div></div> <div class="tail-container" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36><div class="tail" data-v-2b653b36></div></div></div></div></div></div></div></div></div></div> <p class="sidebar-heading open"><span>Angular框架解读</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-0-prestart.html" aria-current="page" class="active sidebar-link">0.预热篇</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-0-prestart.html#前端框架" class="sidebar-link">前端框架</a></li><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-0-prestart.html#angular-框架解读" class="sidebar-link">Angular 框架解读</a></li><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-0-prestart.html#结束语" class="sidebar-link">结束语</a></li></ul></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-metadata.html" class="sidebar-link">1.元数据和装饰器</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-dom-define.html" class="sidebar-link">2.视图抽象定义</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-zonejs.html" class="sidebar-link">3.Zone区域之zone.js</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-zone-ngzone.html" class="sidebar-link">4.Zone区域之ngZone</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-module.html" class="sidebar-link">5.模块化组织</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-di-1-basic-concepts.html" class="sidebar-link">6.依赖注入的基本概念</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-di-2-hierarchical-di.html" class="sidebar-link">7.多级依赖注入设计</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-di-3-bootstrap.html" class="sidebar-link">8.依赖注入的引导过程</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-ivy-0-design.html" class="sidebar-link">9.Ivy编译器整体设计</a></li><li><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-ivy-1-view-data-and-node-injector.html" class="sidebar-link">10.Ivy编译器的视图数据和依赖解析</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>玩转 Angular</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>试试 Cycle.js</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>D3.js 和 Tree</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>试试 Three.js</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>BOX2D.js 文档与教程</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><p>作为“为大型前端项目”而设计的前端框架，Angular 其实有许多值得参考和学习的设计，本系列主要用于研究这些设计和功能的实现原理。本文作为背景和铺垫，先简单以我自身的了解来介绍一下 Angular 这个框架把吧。</p> <h2 id="前端框架"><a href="#前端框架" class="header-anchor">#</a> 前端框架</h2> <h3 id="三大前端-框架"><a href="#三大前端-框架" class="header-anchor">#</a> 三大前端“框架”</h3> <p>虽然这几年前端的发展和变化十分迅猛，但被公认为前端“框架”的 Top3 位置却没有什么变化，依然是 Angular/React/Vue。</p> <p>其中，React/Vue 专注于构建用户界面，在一定程度上来说为一个 Javascript 库；而 Angular 则提供了前端项目开发中较完整的解决方案。我们可以简单粗暴地这样认为：</p> <div class="language- extra-class"><pre class="language-text"><code>Angular = React/Vue + 路由库（react-router/vue-router） + 状态管理（Redux/Flux/Mobx/Vuex） + 脚手架/构建（create-react-app/Vue CLI/Webpack） + ...
</code></pre></div><h3 id="低热度的-angular"><a href="#低热度的-angular" class="header-anchor">#</a> 低热度的 Angular</h3> <p>作为三大前端框架之一，Angular 在国内的热度实在是低。个人认为原因包括：</p> <ul><li>AngularJS 到 Angular2 的断崖式升级，失去了很多开发者的信任</li> <li>Angular 除了依赖注入（Provider/Service）、指令/管道等功能设计，在断崖升级时引入的 Typescript/Decorator/模块化组织/AOT/JIT 等新的能力，对当时大多数前端开发带来了不少的学习门槛</li> <li>Angular 针对大型应用而引入的设计和功能，对于大多数前端应用来说无法物尽其用，反而增加了学习成本</li> <li>Angular 提供了一整套完整的解决方案，反而不像 Vue/React 等库灵活，可以随意搭配其他的状态管理、构建库等（其实也是可以的，可能成本和门槛会高一些），显得笨重</li></ul> <p>由于以上原因，大家在选框架的时候常常讨论的是用 React 还是 Vue，虽然同样作为热门框架，Angular 似乎在无形中就被大家排除在外。使用 Angular 框架的人越少，相关的中文相关的文档和教程也会很少，大家对它的了解和认知都容易不够全面。</p> <p>其实，很多人会问我喜欢 React 还是 Vue，我总会告诉他们我喜欢 Angular，他们也总会觉得很奇怪哈哈哈哈。实际上，AngularJS 是我最早接触的一个前端框架，我也曾经使用过断崖式升级的 Angular2，它们带给我的除了很多未知的知识和领域，还有拓宽了我对前端编程的一些认知。我想，喜欢 Angular，也可能是因为有一些缘分在内的原因叭~</p> <h3 id="我对-angular-的理解"><a href="#我对-angular-的理解" class="header-anchor">#</a> 我对 Angular 的理解</h3> <p>Angular2 的出现时间大概在 2017 年前后，那会 React 的函数式编程正开始受到很多人追捧，而 Vue 也开始进入大家的视野中。但 Angular2 带来的技术和设计很是前卫，以至于对很多人来说门槛太高。</p> <p>但是，如今 2021 年了，我们再来回看一下，Angular 框架中使用到的很多技术和设计，都渐渐地被更多的人在使用了。</p> <p>其中最火的便是 Typescript，显然，如今对大多数前端开发来说，Typescript 都是需要掌握的。在 Angular 之后，React、Vue 也都支持了 Typescript，Vue3 更是直接使用 Typescript 来重构了。</p> <p>除此之外，模块化、AOT/JIT、依赖注入等设计，以及 Rxjs 、元数据（<code>Reflect.metadata</code>）的引入等，也被更多的产品和工具库使用。当然，这里并不是说这些产品和工具是参考了 Angular。Angular 中的这些设计理念，大多数也并不是由 Angular 第一个提出的，但 Angular 大概是第一个在前端框架中（甚至是在前端领域中）将它们毫无违和感地一起引入并使用的。</p> <p>这样的趋势，我认为很大的原因是前端应用的规模在不断变大，这也是因为前端的技术栈在不断拓展，负责的领域也逐渐在扩大。前端应用慢慢地变得复杂，比如 VsCode 编辑器、在线文档编辑这些，项目本身的复杂度和规模都不小，而这样大型的项目里肯定需要往模块化组织的方向发展，那么想必各个模块间的依赖耦合会很严重，因此依赖注入便是一个很好的方式来管理，VsCode 便是这样做的。</p> <p>当然，即使在未来，大型项目在所有前端项目中的占比肯定也不至于很高，但大型项目如何设计和管理这块领域对前端来说依然比较陌生。我们可以借助常见的后台系统架构设计来进行参考和反思，比如微服务、领域驱动设计、职责驱动设计等。但这些终究是设计思想，如何才能很好地落地，对前端开发都是不小的考验。</p> <p>我接触过各式各样的项目，而当这些项目在面对项目的规模变大的时候，虽然新人的加入、每个人都按照自己的想法去开发，最终总会变得难以维护，历史债务十分严重。而 Angular 则是唯一一个能限制开发的自由发挥的，可以让经验不足和经验丰富的开发都写出一样易维护的代码。</p> <p>回归主题，既然 Angular 提供了大型前端应用的完整解决方案，那么我们不妨多些对它的学习和了解，当我们真正遇到问题的时候，便多了一个可落地方案的参考，这也是为什么我们要不断汲取新知识和技术的原因。</p> <h2 id="angular-框架解读"><a href="#angular-框架解读" class="header-anchor">#</a> Angular 框架解读</h2> <p>源码阅读对很多人来说，都是一件挑战很大的事情，对我来说也一样。</p> <p>虽然我有较多地阅读过 Vue 的源码（可参考<a href="http://www.godbasin.com/vue-ebook/" target="_blank" rel="noopener noreferrer">《深入理解 Vue.js 实战》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>这本书），但前提是我对这个框架有足够多的理解和使用经验，在尝试介绍和解说时，也更是倾向使用者的角度来进行。而对于 React，则是因为理解和使用经验的缺乏，未曾有机会深入地去了解它，但也有阅读过写得不错的源码解读（可参考<a href="https://github.com/BetaSu/just-react" target="_blank" rel="noopener noreferrer">《React 技术揭秘》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>一书）。</p> <p>对于阅读源码来说，最好的方式便是从已知的理解和认知中开始。阅读源码，并不是为了熟悉掌握源码本身，更是为了掌握其中的一些值得借鉴的思考方式和设计，因此我也尽可能减少代码占据的篇幅，使用自己理解后的方式来进行描述。</p> <p>那么，后面我会从自己认为最值得参考和学习的地方开始，一点点学习其中的精华。以我当前有限的认知，大概会包括以下内容：</p> <ul><li>依赖注入整体框架的设计</li> <li>组件设计与管理</li> <li>Provider 与 Service 的设计</li> <li>NgModule 模块化组织（多级/分层）的设计</li> <li>模板引擎/模板编译过程的整体设计</li> <li>Zone 设计：提升计算速度</li> <li>JIT/AOT 设计</li> <li>元数据设计：（<code>Reflect.metadata</code>）的引入和使用思考</li> <li>响应式编程：Rxjs 的引入和使用思考</li></ul> <p>在时隔 3 年之后再次接触 Angular，还是直接以阅读源码的方式来进行，对我来说是个不小的挑战。但这些年来，我也一直在尝试做各种不同的新的事情，如果因为觉得困难而放弃，那么这个天花板便是我自身，而不是什么“环境所迫”、“没有时间”这样的借口。或许我会写得很慢，但我依然希望自己能一点点去细细钻研，也希望至少以上的内容能最终掌握。</p> <p>这是一个大工程，因为我写下这篇文章来给自己预热，也希望能打打气，更是尝试立下一个 FLAG 吧。</p> <h2 id="结束语"><a href="#结束语" class="header-anchor">#</a> 结束语</h2> <p>这是一篇从我个人的理解出发的文章，同样的这个系列也会以我一个人这样局限的角度来出发进行介绍。因此它们或许可能存在片面和局限的时候，但我希望即使是这样的内容，也能给你们带来一些思考和收获。</p> <p>分享和交流，并不是为了各自的理由而争执，而是为了弥补自己看不到的一面，共同进步，不是吗？</p></div> <!----> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/godbasin/front-end-playground/edit/sourcecode/docs/front-end-others/deep-into-angular/angular-design-0-prestart.md" target="_blank" rel="noopener noreferrer">帮阿猪改善此页面！</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----> <blockquote>部分文章中使用了一些网站的截图，如果涉及侵权，请告诉我删一下谢谢~</blockquote> <div style="margin-top:30px;"><div class="el-row" style="margin-left:-10px;margin-right:-10px;"><div class="el-col el-col-24 el-col-sm-0 el-col-md-2 el-col-lg-4" style="padding-left:10px;padding-right:10px;display:block;"><div style="width:1px;height:1px;"></div></div> <div class="el-col el-col-24 el-col-sm-24 el-col-md-18 el-col-lg-16" style="padding-left:10px;padding-right:10px;"><div class="el-card box-card is-always-shadow"><div class="el-card__header"><div class="clearfix"><span>温馨提示喵</span></div></div><div class="el-card__body"> <div class="el-row" style="margin-left:-10px;margin-right:-10px;"><div class="el-col el-col-24 el-col-xs-24 el-col-sm-12" style="padding-left:10px;padding-right:10px;"><div class="el-image"><div class="image-slot"><img src="https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/assets/img/loading.gif" style="width:100%;"></div><!----></div></div> <div class="el-col el-col-24 el-col-xs-24 el-col-sm-12" style="padding-left:10px;padding-right:10px;"><div class="copyright-text"><div>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</div> <div>出处：被删的前端游乐场</div> <div>作者：<a href="https://github.com/godbasin" target="_blank">被删</a></div></div></div></div></div></div></div></div></div></footer> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/front-end-playground/front-end-others/deep-into-angular/angular-design-metadata.html">
          1.元数据和装饰器
        </a>
        →
      </span></p></div>  <div class="gitalk-container theme-default-content"><div id="gitalk-container" class="content"></div></div></main> <div id="kitty-container"><span><div role="tooltip" id="el-popover-2246" aria-hidden="true" class="el-popover el-popper" style="width:undefinedpx;display:none;"><!----><img src="https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/2code2.jpg" class="image"> <div class="text">牡羊猪的猫粮罐</div> </div><span class="el-popover__reference-wrapper"><div id="kitty" style="background:url(https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/assets/img/kitty0.svg);"></div></span></span> <div class="el-dialog__wrapper" style="display:none;"><div role="dialog" aria-modal="true" aria-label="牡羊猪是这样渐渐胖成猪的喵（点击图片可以切换噢）" class="el-dialog" style="margin-top:15vh;"><div class="el-dialog__header"><span class="el-dialog__title">牡羊猪是这样渐渐胖成猪的喵（点击图片可以切换噢）</span><button type="button" aria-label="Close" class="el-dialog__headerbtn"><i class="el-dialog__close el-icon el-icon-close"></i></button></div><!----><!----></div></div></div></div><div class="global-ui"></div></div>
    <script src="/front-end-playground/assets/js/app.1e2670bf.js" defer></script><script src="/front-end-playground/assets/js/2.38d016d1.js" defer></script><script src="/front-end-playground/assets/js/3.e3f029cb.js" defer></script><script src="/front-end-playground/assets/js/103.4038836d.js" defer></script>
  </body>
</html>
